package com.lesports.qmt.image.web.api.controller.support;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.lesports.api.common.ImageUrlExt;
import com.lesports.qmt.image.web.api.core.Constants;
import com.lesports.qmt.image.web.api.param.Coordinate;
import com.lesports.qmt.image.web.api.utils.ImageUtils;
import com.lesports.spring.boot.exception.LeWebApplicationException;
import com.lesports.spring.boot.mvc.LeStatus;
import com.lesports.utils.LeDateUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * Created by denghui on 2016/12/28.
 */
public abstract class AbstractUploadController {
    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractUploadController.class);
    private static Map<String, List<Integer>> ratioMap = Maps.newHashMap();

    static {
        //1610(16:10) 169(16:9) 43(4:3) 34(3:4) 21(2:1) 11(1:1)
        ratioMap.put("1610", Lists.newArrayList(16,10));
        ratioMap.put("169", Lists.newArrayList(16,9));
        ratioMap.put("43", Lists.newArrayList(4,3));
        ratioMap.put("34", Lists.newArrayList(3,4));
        ratioMap.put("21", Lists.newArrayList(2,1));
        ratioMap.put("11", Lists.newArrayList(1,1));
    }

    protected String copyFileToLocal(MultipartFile multipartFile, String imagePath) throws IOException {
        //生成本地路径
        java.nio.file.Path localDir = Paths.get(Constants.IMAGE_SOURCE_PATH + imagePath.substring(0,imagePath.lastIndexOf(Constants.FILE_SEPARATOR)));
        if (!Files.exists(localDir)) {
            Files.createDirectories(localDir);
        }
        //复制文件
        java.nio.file.Path localPath = Paths.get(Constants.IMAGE_SOURCE_PATH + imagePath);
        Files.copy(multipartFile.getInputStream(), localPath);
        return localPath.toString();
    }

    protected String genImagePath(MultipartFile multipartFile) {
        String filename = genFilename(multipartFile);
        String now = LeDateUtils.formatYYYYMMDDHHMMSS(new Date());
        return Constants.IMAGE_WEB_2 + Constants.FILE_SEPARATOR + now.substring(0,8) + Constants.FILE_SEPARATOR
                + RandomStringUtils.randomAlphanumeric(9).toLowerCase() + Constants.FILE_SEPARATOR + filename;
    }

    protected String genFilename(MultipartFile multipartFile) {
        String originalFileName = multipartFile.getOriginalFilename();
        String originalFileType = originalFileName.substring(originalFileName.lastIndexOf(Constants.FILE_DOT));
        return UUID.randomUUID().toString() + ImageUtils.transFormatTypetoLowerCase(originalFileType);
    }

    protected ImageUrlExt buildResponse(String imagePath, String imageUrl) {
        if (StringUtils.isEmpty(imageUrl) || StringUtils.isEmpty(imagePath)) {
            throw new LeWebApplicationException("fail to upload", LeStatus.SERVER_EXCEPTION);
        }
        ImageUrlExt imageUrlExt = new ImageUrlExt();
        imageUrlExt.setUrl(imageUrl);
        imageUrlExt.setPath(imagePath);
        return imageUrlExt;
    }

    protected String getValidParams(String params, int width, int height) {
        Map<String, Object> map = JSON.parseObject(params, Map.class);
        for (Map.Entry<String, Object> param : map.entrySet()) {
            String ratio = param.getKey();
            if (ratioMap.containsKey(ratio)) {
                Coordinate coordinate = JSON.parseObject(param.getValue().toString(), Coordinate.class);
                if (coordinate.getX() == 0 && coordinate.getY() == 0
                        && coordinate.getW() == 0 && coordinate.getH() == 0) {
                    param.setValue(JSON.toJSONString(getAutoCoordinate(ratio, width, height)));
                }
            } else {
                LOGGER.warn("unknown ratio, width:{}, height:{}, ratio:{}", width, height, ratio);
            }
        }
        return JSON.toJSONString(map);
    }

    protected Coordinate getAutoCoordinate(String ratio, int width, int height) {
        // (x:y) (w:h)
        int x = 0, y = 0, w = width, h = height;
        int unitW = ratioMap.get(ratio).get(0);
        int unitH = ratioMap.get(ratio).get(1);
        int candidateH = unitH*width/unitW;
        int candidateW = unitW*height/unitH;
        if (candidateH <= height) {
            x = 0;
            y = (height - candidateH) / 2;
            w = width;
            h = candidateH;
        } else if (candidateW <= width) {
            x = (width - candidateW) / 2;
            y = 0;
            w = candidateW;
            h = height;
        } else {
            LOGGER.warn("should not happen here, width:{}, height:{}, ratio:{}", width, height, ratio);
        }
        Coordinate auto = new Coordinate(x,y,w,h);
        LOGGER.info("auto coordinate: {}", auto);
        return auto;
    }
}
